﻿using System;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Newtonsoft.Json;
using FSLib.Network.Http;
namespace SignTest
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            FaceCheckeInfo faceCheckeInfo = new FaceCheckeInfo();
            string datetime = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            string message = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(faceCheckeInfo)));
            string version = "1.0.0";
            string appId = "d2138b9e9e3944f3a7f9c748360e7a3d";
                             
            string message_id = Guid.NewGuid().ToString();
            string appKey = @"-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD8x2zk10ZiGdWbTZ5MjbuV1ZNwKG8UboiVP9X4lcBdqHOt4bks2L0A8tiNEYV1OwBLlZ3Qy3FvgQEv+6VZVtJTKYuMWED1Ysx2bOlzYTT/vNDxgadWpzmTbl3ThUZ0wlHO+hZTnibfGohC7bB4VxLRzau5wIM6p+IvpkwoubQKqyY2VA8V1uXe2GQMhZ+ARRGmNct6ZdfRfU3a6mU9yPCPPgZ59BKj4uXV8kBcmJWqsSjNvIhmvtFbPj5vSmwPcyemK9iquhPND7UcdRYCVh2raS+jMFR3LfNVO5idfE6nhL3aKXNOhSmVwq24GqkO/FONUV8Dti0gsFykhF0k4JiLAgMBAAECggEBAKXYWdOSgjUe6gyo0jE71FUr+T3e6XIoSyhQ55ve9IT+Xlc4/3szAF489mMnmb4eZcUxdodk0xnrM9I9cnC5C+lQGqSLyqK0nZ0dO9Vdc55OTXAGNrodoSLfiGOcz2sPiwkW/8sAulQqXjg7JkruJgTMwdxvOColt7q3isQ1grBz6CK1dM6YZICP+mvGXpHc3tHK0XbCjt3/pUasYcZLzj/NA+nzxur9QSyni8hYN08zxTXATblExu1tglXBH1a6nvbIbqmFOYxvfSJ4tP2VExvyypPkp9VCq4rmvwqi88Q0NFRqyJ7x9DGC1dPobK/AMN+O/nrFZTSuxA8fsyXS3sECgYEA/wLKt7zGOUKIGQZN6sDj6yfbCW8GfkmUC2TuwLw23YMET76C7kv9nMzxWf2X9IJ4wQcCvLQLrSVHRRKiRWIWZIP8YNKmAkuRePOTTforghELFn4PzWqHarwyfsF93Xq5knvHETN2oRdB2j5We+w2Q+xtvhvtA7m23XWdRIg2tBsCgYEA/cJq2VF8G//3BDYwNtL1dGB09X/XAr7Zdm9yocNr95FI2Zd4nV3uhkm9j2k7JSreiWr7K9F0NX/TFhA/28GCmCOVCu0Yigw7xQyE5+UM/VuUatCQeMvuGt9ZCV8AJ4Ufta7QJAJww3ajXKJSZXUY3L/EJRGIyi1gxz+NBqV2lFECgYBF8kYYT7cvTYh3FLuagH4DqlLyK3nkedoZpf227+k8qQsttFvFcSKHN8+bl2turbrhd0LQ77GkNG1wDMRls5ngyDMZe639Qy0LuAPXh58XdgVMjhdXiLjMFgLjsb8MWPU9sKXRmgQX+4Eck6y1IP1hdCBF3PMN6oq2A+S3P4WBsQKBgQCgjXa/IuAscwnd308oENd+F11IyubF9OxwE9lqYdOY4pI+IakNoBW/Xz6RUxo5zOLZ/RcHxVEKXGK4zfUpXEj9a13seNCS32SdqusYMYLDdkL0RhtyYky3MeMKm9HkL0U91WoZrnWcJh78CDOrv6fIW4iFj4+Fo6pcxme68cuR0QKBgCSrK4Gwnl3jVkJrYO9rB1d1x7jmvx4tqyjdLqdTi6WaruWtr6FdRuzLlhbtcA923ThpYJ6ZRHDkSMyOxaOKWipiTqQ+gyBA89DXDuYy9u+7owtF6IuZiCi6Vn+JPyhaZWWKE2P7wgwcCJSMJ0TeI73MtpUPekSBhlZf2g4X/eTI -----END PRIVATE KEY-----";
            await Console.Out.WriteLineAsync(appKey.Length.ToString());
            StringBuilder sb = new StringBuilder();
            sb.Append(appId);
            sb.Append(datetime);
            sb.Append(message);
            sb.Append(version);
            sb.Append(message_id);
            string ss = Hash(sb.ToString());
            Console.WriteLine(ss);
            Console.WriteLine(ss.Length);
            string singRes3 = CryptoUtil.SignWithRsa(appKey, ss);
            await Console.Out.WriteLineAsync(singRes3);
            FaceCheckeRequest
                request = new FaceCheckeRequest()
                {
                    datetime = datetime,
                    message = message,
                    signature = singRes3
                };
            await Upload("http://1.71.182.111:10066/prod-api/api/v1/faceCheck", request,appId, message_id);
            Console.WriteLine(singRes3);
            Console.ReadLine();
        }
        /// <summary>
        /// 签名字符串
        /// </summary>
        /// <param name="prestr">需要签名的字符串</param>
        /// <param name="key">密钥</param>
        /// <returns>签名结果</returns>
        public static string Sign(string prestr, string key)
        {
            string inputCharset = "utf-8";
            StringBuilder sb = new StringBuilder(32);

            prestr = prestr + key;

            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] t = md5.ComputeHash(Encoding.GetEncoding(inputCharset).GetBytes(prestr));
            for (int i = 0; i < t.Length; i++)
            {
                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
            }

            return sb.ToString().ToUpper();
        }

        public static string Hash(string input)
        {
            MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
            byte[] hashedDataBytes;
            hashedDataBytes = md5Hasher.ComputeHash(Encoding.GetEncoding("UTF-8").GetBytes(input));
            StringBuilder tmp = new StringBuilder();
            foreach (byte i in hashedDataBytes)
            {
                tmp.Append(i.ToString("X2"));
            }
            return tmp.ToString();
        }

        private static byte[] SignWithPrivateKey(string privateKey, string data)
        {
            using (RSA rsa = RSA.Create())
            {
                // 从私钥字符串加载 RSA 密钥

                rsa.ImportFromPem(privateKey.ToCharArray());
                byte[] dataBytes = Encoding.UTF8.GetBytes(data);
                return rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
                // 签名数据

            }
        }
        private static async Task Upload(string url, FaceCheckeRequest faceCheckeReques,string appId, string message_id)
        {
           
            var datas = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(faceCheckeReques)));
            FSLib.Network.Http.HttpClient client = new FSLib.Network.Http.HttpClient();
            client.Setting.Headers.Add("app_id", appId);
            client.Setting.Headers.Add("message_id", message_id);
            var ctx = client.Create<string>(FSLib.Network.Http.HttpMethod.Post, url, data: datas, contentType: ContentType.Json);
            await ctx.SendAsync();
            if (ctx.IsValid())
            {
                var result = ctx.Result;
                Console.WriteLine(result);
            }
            else
            {

            }
        }
    }

    public class FaceCheckeInfo
    {
        public string cardNo { get; set; } = "32082619910912385X";
        public string mac { get; set; } = "30:1F:9A:82:78:45";
        public string realName { get; set; } = "陈大峰";
        public string nation { get; set; } = "汉族";
    }
    public class FaceCheckeRequest
    {
        public string signature { get; set; }
        public string datetime { get; set; }
        public string version { get; set; } = "1.0.0";
        public string message { get; set; }
    }

    public class FaceSigoneRequest
    {
        public string cardNo { get; set; } = "140202200003022258";
        public string mac { get; set; } = "8A:92:04:6A:F2:89";
        public string realName { get; set; } = "张三";
        /// <summary>
        /// 证件照
        /// </summary>
        public string img { get; set; }
        /// <summary>
        /// 学员照片
        /// </summary>
        public string personPhoto { get; set; }
    }
    public class CryptoUtil
    {
        // MD5 计算
        public static string CalculateMd5(string input)
        {
            using (var md5 = MD5.Create())
            {
                byte[] inputBytes = Encoding.UTF8.GetBytes(input);
                byte[] hashBytes = md5.ComputeHash(inputBytes);
                return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
            }
        }

        // RSA 签名
        public static string SignWithRsa(string privateKey, string data)
        {
            using (var rsa = RSA.Create())
            {
                rsa.ImportFromPem(privateKey.ToCharArray());
                byte[] dataBytes = Encoding.UTF8.GetBytes(data);
                byte[] signedBytes = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                return Convert.ToBase64String(signedBytes);
            }
        }

        // RSA 验证
        public static bool VerifyWithRsa(string publicKey, string data, string signature)
        {
            using (var rsa = RSA.Create())
            {
                rsa.ImportFromPem(publicKey.ToCharArray());
                byte[] dataBytes = Encoding.UTF8.GetBytes(data);
                byte[] signatureBytes = Convert.FromBase64String(signature);
                return rsa.VerifyData(dataBytes, signatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            }
        }
    }
}
